<html>
<head><meta charset="utf-8"><title>UnsafeCell&lt;AtomicU32&gt; · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html">UnsafeCell&lt;AtomicU32&gt;</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="178132940"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178132940" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178132940">(Oct 14 2019 at 19:50)</a>:</h4>
<p>Hi, I'm not sure if this is the best place to ask (or even how to use zulip). I've used UnsafeCell&lt;AtomicU32&gt; in order to perform unsynchronized loads when I can guarantee that other threads <em>only</em> load from that atomic (never store). Is this safe? <a href="https://github.com/tokio-rs/tokio/blob/3a941e99a112f0058d2ac1f295da29491ba4b232/tokio-executor/src/loom/atomic_u32.rs#L25-L27" target="_blank" title="https://github.com/tokio-rs/tokio/blob/3a941e99a112f0058d2ac1f295da29491ba4b232/tokio-executor/src/loom/atomic_u32.rs#L25-L27">https://github.com/tokio-rs/tokio/blob/3a941e99a112f0058d2ac1f295da29491ba4b232/tokio-executor/src/loom/atomic_u32.rs#L25-L27</a></p>



<a name="178132954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178132954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178132954">(Oct 14 2019 at 19:50)</a>:</h4>
<p>I am pretty sure it is, but got a comment on HN and i was not sure how to respond: <a href="https://news.ycombinator.com/item?id=21251778" target="_blank" title="https://news.ycombinator.com/item?id=21251778">https://news.ycombinator.com/item?id=21251778</a></p>



<a name="178133319"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133319" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133319">(Oct 14 2019 at 19:55)</a>:</h4>
<p>It is UB, and I got some actual miscompilation on one of my programs while trying something similar so it's not a theoretical concern.</p>



<a name="178133446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133446">(Oct 14 2019 at 19:56)</a>:</h4>
<p>Further, <code>UnsafeCell&lt;AtomicXyz&gt;</code> is redundant because <code>AtomicXyz</code> already contains an <code>UnsafeCell&lt;Xyz&gt;</code>.</p>



<a name="178133480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133480">(Oct 14 2019 at 19:57)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> what part is UB?</p>



<a name="178133512"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133512" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133512">(Oct 14 2019 at 19:57)</a>:</h4>
<p>Loading from an UnsafeCell some data which may have ever been touched by another thread.</p>



<a name="178133547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133547">(Oct 14 2019 at 19:58)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> by touched, you mean mutated? In this case, there are no mutations from other threads</p>



<a name="178133589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133589">(Oct 14 2019 at 19:58)</a>:</h4>
<p>The problem is that even with UnsafeCell, the compiler can assume that if it knows about all memory accesses in the current thread, it knows about all memory accesses, period.</p>



<a name="178133612"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133612" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133612">(Oct 14 2019 at 19:58)</a>:</h4>
<p>So it can optimize out "redundant" loads and so on.</p>



<a name="178133626"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133626" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133626">(Oct 14 2019 at 19:58)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> in this case, it does know about all stores in the thread</p>



<a name="178133655"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133655" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133655">(Oct 14 2019 at 19:58)</a>:</h4>
<p>And there are no stores from other threads and have never been?</p>



<a name="178133688"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133688" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133688">(Oct 14 2019 at 19:59)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> all stores are guarded by locks and the unsync_load happens within the lock</p>



<a name="178133711"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133711" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133711">(Oct 14 2019 at 19:59)</a>:</h4>
<p>Oh, if you have a lock, then that is your synchronization.</p>



<a name="178133726"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133726" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133726">(Oct 14 2019 at 19:59)</a>:</h4>
<p>In that case, you don't need Atomic, you could use UnsafeCell&lt;u32&gt; directly.</p>



<a name="178133794"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133794" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133794">(Oct 14 2019 at 20:00)</a>:</h4>
<p>(unless you sometimes want to access the atomic without going through the lock)</p>



<a name="178133821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133821">(Oct 14 2019 at 20:00)</a>:</h4>
<p>By the way, what's wrong with just doing atomic loads and stores with <code>Relaxed</code> ordering?</p>



<a name="178133824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133824">(Oct 14 2019 at 20:00)</a>:</h4>
<p>100% of mutations are in the lock, only loads are outside of the lock</p>



<a name="178133879"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178133879" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178133879">(Oct 14 2019 at 20:01)</a>:</h4>
<blockquote>
<p>100% of mutations are in the lock, only loads are outside of the lock</p>
</blockquote>
<p>But how do you make sure that the mutations are propagated to the threads doing the load?</p>



<a name="178134026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134026">(Oct 14 2019 at 20:03)</a>:</h4>
<p>At the hardware level, <code>load(Relaxed)</code> should compile down to a normal load instructions on all current CPUs. But at the compiler level, it serves as a warning that the value may have changed as a result of another thread modifying it, and the compiler should go check it from time to time.</p>



<a name="178134162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134162">(Oct 14 2019 at 20:04)</a>:</h4>
<p>(Currently, LLVM pessimistically interprets this as a command to go check the value <em>every single time</em>, but most other experts I know agree with me that this is an LLVM optimizer bug)</p>



<a name="178134255"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134255" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134255">(Oct 14 2019 at 20:06)</a>:</h4>
<p>There is heavier synchronization else where that guarantees it</p>



<a name="178134303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134303">(Oct 14 2019 at 20:06)</a>:</h4>
<p>When you acquire a lock (or use an atomic with <code>Acquire</code> ordering, which is what the lock implementation does under the hood), the compiler automatically treats every shared variable which you're going to manipulate inside of the lock like this. But without a lock, you need to hint the compiler at the necessity of refreshing its local cache of the shared variable.</p>



<a name="178134327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134327">(Oct 14 2019 at 20:07)</a>:</h4>
<p>Oh, if you have heavier synchronization then you should probably be fine.</p>



<a name="178134333"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134333" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134333">(Oct 14 2019 at 20:07)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> the details are in this post: <a href="https://tokio.rs/blog/2019-10-scheduler/" target="_blank" title="https://tokio.rs/blog/2019-10-scheduler/">https://tokio.rs/blog/2019-10-scheduler/</a> (including how other threads are notified)</p>



<a name="178134617"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134617" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134617">(Oct 14 2019 at 20:10)</a>:</h4>
<p>Reading through...</p>
<div class="codehilite"><pre><span></span><span class="c1">// safety: this is the **only** thread that updates this cell.</span>
<span class="kd">let</span><span class="w"> </span><span class="n">tail</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">tail</span><span class="p">.</span><span class="n">unsync_load</span><span class="p">();</span><span class="w"></span>
</pre></div>


<p>I agree with the safety note stating that this should work, but I would just use <code>load(Relaxed)</code> unless I have a benchmark proving that there's a performance benefit in not doing so, for the sake of sticking with familiar abstractions.</p>



<a name="178134670"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134670" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134670">(Oct 14 2019 at 20:11)</a>:</h4>
<p>If I had to do it, then I would do it by transmuting <code>&amp;AtomicU32</code> into <code>&amp;UnsafeCell&lt;u32&gt;</code> or just plain <code>*const u32</code> (I believe there are some <code>repr(transparent)</code> in the right places that makes those transmutes okay).</p>



<a name="178134818"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134818" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134818">(Oct 14 2019 at 20:13)</a>:</h4>
<p>I've run benchmarks where the unsync load is measurably faster than a relaxed load</p>



<a name="178134845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134845">(Oct 14 2019 at 20:13)</a>:</h4>
<p>Most likely the aforementioned LLVM optimizer bug, sigh.</p>



<a name="178134846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134846">(Oct 14 2019 at 20:13)</a>:</h4>
<p>there was a previous thread w/ <span class="user-mention" data-user-id="120791">@RalfJ</span> on a similar optimization in the <code>bytes</code> crate</p>



<a name="178134853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134853">(Oct 14 2019 at 20:13)</a>:</h4>
<p>:(</p>



<a name="178134909"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134909" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134909">(Oct 14 2019 at 20:14)</a>:</h4>
<p>(the one in bytes was definitely UB though... )</p>



<a name="178134940"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178134940" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178134940">(Oct 14 2019 at 20:14)</a>:</h4>
<p>Well, then again, casting <code>&amp;AtomicU32</code> to <code>*const u32</code> followed by a ptr::read() should work if you are the only thread writing there. It's ugly, but not UB.</p>



<a name="178135231"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178135231" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178135231">(Oct 14 2019 at 20:18)</a>:</h4>
<p>The unsync_load() in pop() should work for the same reason.</p>



<a name="178135404"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178135404" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178135404">(Oct 14 2019 at 20:20)</a>:</h4>
<p>Do you have a pointer to the steal() impl? It's not featured in the blog post...</p>



<a name="178136004"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136004" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136004">(Oct 14 2019 at 20:27)</a>:</h4>
<p>(PS: I agree with what you say in the blog post. Sometimes, people who discover atomics undergo a bit of a "kid in a candy store" phase and forget that locking an uncontended mutex is just an atomic swap and unlocking an uncontended mutex is just an atomic store, both of which are <em>really</em> cheap. As the Preshing blog says, well-implemented locks are not slow, contention is.)</p>



<a name="178136117"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136117" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136117">(Oct 14 2019 at 20:28)</a>:</h4>
<p>(Be it contention on the lock, or contention on the CPU cache lines that it protects, which are invalidated on every write)</p>



<a name="178136318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136318">(Oct 14 2019 at 20:31)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> <a href="https://github.com/tokio-rs/tokio/blob/new-scheduler/tokio-executor/src/thread_pool/queue/local.rs#L201-L240" target="_blank" title="https://github.com/tokio-rs/tokio/blob/new-scheduler/tokio-executor/src/thread_pool/queue/local.rs#L201-L240">https://github.com/tokio-rs/tokio/blob/new-scheduler/tokio-executor/src/thread_pool/queue/local.rs#L201-L240</a></p>



<a name="178136391"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136391" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136391">(Oct 14 2019 at 20:32)</a>:</h4>
<p><code>dst.tail.unsync_load()</code> looks wrong.</p>



<a name="178136407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136407">(Oct 14 2019 at 20:32)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> it's confusing, but self &amp; dst are probably ordered wrong</p>



<a name="178136429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136429">(Oct 14 2019 at 20:32)</a>:</h4>
<p>from an API pov</p>



<a name="178136436"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136436" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136436">(Oct 14 2019 at 20:32)</a>:</h4>
<p><code>dst</code> is owned by the calling thread</p>



<a name="178136443"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136443" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136443">(Oct 14 2019 at 20:32)</a>:</h4>
<p>where as <code>self</code> is the remote thread</p>



<a name="178136483"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136483" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136483">(Oct 14 2019 at 20:33)</a>:</h4>
<p>Yup, that's definitely confusing.</p>



<a name="178136563"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136563" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136563">(Oct 14 2019 at 20:34)</a>:</h4>
<p>Consider changing it so that <code>self</code> is the receiver and the input parameter is an <code>src</code> queue that is being stolen from.</p>



<a name="178136576"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136576" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136576">(Oct 14 2019 at 20:34)</a>:</h4>
<p><span class="user-mention" data-user-id="211871">@Hadrien Grasland</span> my thought would be to make <code>steal</code> a free fn</p>



<a name="178136587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136587">(Oct 14 2019 at 20:34)</a>:</h4>
<p>Works as well.</p>



<a name="178136609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136609">(Oct 14 2019 at 20:34)</a>:</h4>
<p>or, it could be <code>steal_from(self, src)</code></p>



<a name="178136659"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136659" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136659">(Oct 14 2019 at 20:35)</a>:</h4>
<p>Also, consider replicating your safety note on this unsync_load() (you did make this function unsafe, right?)</p>



<a name="178136737"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136737" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136737">(Oct 14 2019 at 20:36)</a>:</h4>
<p>unsync_load is unsafe</p>



<a name="178136901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136901">(Oct 14 2019 at 20:38)</a>:</h4>
<p>I am a bit surprised by this:</p>
<div class="codehilite"><pre><span></span><span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">src_head</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">head</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Acquire</span><span class="p">);</span><span class="w"></span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">src_tail</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">tail</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Acquire</span><span class="p">);</span><span class="w"></span>

<span class="w">            </span><span class="c1">// Number of available tasks to steal</span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">src_tail</span><span class="p">.</span><span class="n">wrapping_sub</span><span class="p">(</span><span class="n">src_head</span><span class="p">);</span><span class="w"></span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"></span>

<span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"></span>

<span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">buffer</span><span class="p">.</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u32</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="n">atomic</span>::<span class="n">spin_loop_hint</span><span class="p">();</span><span class="w"></span>
<span class="w">                </span><span class="c1">// inconsistent, try again</span>
<span class="w">                </span><span class="k">continue</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"></span>
</pre></div>



<a name="178136931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178136931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178136931">(Oct 14 2019 at 20:39)</a>:</h4>
<p>When do you expect the if to fail?</p>



<a name="178137588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178137588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178137588">(Oct 14 2019 at 20:46)</a>:</h4>
<p>Oh, well, I'm being reminded that I should probably go to sleep because it's getting late here and I have a job interview to take care of early tomorrow.</p>



<a name="178137625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178137625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178137625">(Oct 14 2019 at 20:46)</a>:</h4>
<p>But I would definitely enjoy spending more time reviewing this later on, hopefully will find some time tomorrow.</p>



<a name="178138496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178138496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178138496">(Oct 14 2019 at 20:57)</a>:</h4>
<p>good luck!</p>



<a name="178138860"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178138860" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178138860">(Oct 14 2019 at 21:00)</a>:</h4>
<p>so the high-level bit is that <em>if</em> all the racing accesses are reads, then all is fine and there's no UB. (I mean, that's a pattern that can even be written in safe code.)</p>



<a name="178138911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178138911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178138911">(Oct 14 2019 at 21:01)</a>:</h4>
<p>but you'll need some mechanism to ensure a happens-before edge between any critical section (that mutates the data) and any read</p>



<a name="178138945"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178138945" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178138945">(Oct 14 2019 at 21:01)</a>:</h4>
<p><span class="user-mention" data-user-id="224941">@Carl Lerche</span>  it'd help if you had a "minimized example" (even in pseudo-code) of the kind of pattern you are worried about</p>



<a name="178140674"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178140674" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Carl Lerche <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178140674">(Oct 14 2019 at 21:24)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> from a concurrency POV, i'm fairly confident it is correct. The original HN comment was saying that the compiler could insert random data in the field though... which did not sound correct to me.</p>



<a name="178140729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178140729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178140729">(Oct 14 2019 at 21:25)</a>:</h4>
<p>uh... that sounds weird</p>



<a name="178140740"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178140740" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178140740">(Oct 14 2019 at 21:25)</a>:</h4>
<p>I usually take Reddit comments serious but ignore HN comments. ;)</p>



<a name="178147268"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178147268" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178147268">(Oct 14 2019 at 23:21)</a>:</h4>
<p>Meh. Looks like my stupid stressed out brain doesn't want to sleep tonight :(</p>



<a name="178147326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178147326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178147326">(Oct 14 2019 at 23:22)</a>:</h4>
<p>Then I guess I'll just either a/take a look at this code further or b/try to draft some kind of pre-RFC document for atomic volatile. Hmmm...</p>



<a name="178195263"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178195263" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178195263">(Oct 15 2019 at 13:53)</a>:</h4>
<p>Got time to take another look. Overall, what you have here looks pretty reasonable, but would probably be better with a bit of documentation here and there so that things need to be inferred less often.</p>



<a name="178195407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178195407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178195407">(Oct 15 2019 at 13:55)</a>:</h4>
<p>For example, Local::mask should be documented as a power-of-2 modulo optimization for head/tail % buffer.len() computations.</p>



<a name="178195806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178195806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178195806">(Oct 15 2019 at 13:59)</a>:</h4>
<p>It is not immediately obvious that the ptr::read(ptr) in pop() isn't racy. It actually is because both push() and pop() may only be called in the local queue's owner thread. The documentation of that ptr::read could just point that out.</p>



<a name="178196937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178196937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178196937">(Oct 15 2019 at 14:10)</a>:</h4>
<p>The concurrent correctness of steal2(), on its side, is also <em>far</em> from obvious. After all, this can happen:</p>
<p>- Thread A is the owner of the queue, Thread B is the thief.<br>
- Thread B starts stealing, enters steal2(), reads the head/tail info of thread A's local work queue, then for some strange reason stupid OS task scheduler decides to put it to sleep and schedule something else.<br>
- Thread A furiously pushes and pops tasks on its local queue until the tail (pushing end) gets close to the point where thread B measured that thread A's head (popping end) was.<br>
- Thread B wakes up and starts reading what it assumes to be unprocessed thread A tasks, while thread A is simultaneously in the process of overwriting the corresponding memory region. This is a data race.</p>



<a name="178197458"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178197458" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178197458">(Oct 15 2019 at 14:15)</a>:</h4>
<p>Now, Thread B has a good chance of figuring out that this happened and restarting the transaction later on, when it will try to claim the tasks with a CAS of thread A's head pointer. I say good chance, because there is a tiny odd of an ABA issue masking the problem if thread A managed to make its head counter overflow and do a perfect round trip. With AtomicU32, the odds of this happening are probably too small to bother considering them, but this shows that the size of the head and the tail pointers are correctness-critical in this algorithm, which is not documented currently.</p>



<a name="178197572"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178197572" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178197572">(Oct 15 2019 at 14:17)</a>:</h4>
<p>And all this does not eliminate the fact that even if thread B eventually figures out that something went wrong and restarts the transaction, a data race has still occured, so the program technically has undefined behavior from the point of view of the Rust spec.</p>



<a name="178197635"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178197635" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178197635">(Oct 15 2019 at 14:17)</a>:</h4>
<p>My understanding is that you are trying to implement semantics akin to those of a seqlock (try to read, check for race, try again if a race occured), but unfortunately I'm not sure we actually have the right tools for efficiently building those without UB in Rust at this point in time. I believe we'd need something like a well-implemented element-wise atomic memcpy intrinsic, which LLVM has but Rust does not expose right now. And because LLVM is terrible at optimizing Relaxed atomics, naively replacing this intrinsic with an AtomicU8 load/store loop would yield terrible performance at this point in time.</p>
<p>(I wonder if we could write a decent atomic memcpy implementation in pure Rust, without resorting to weird arch-specific tricks like hand-coded <code>REP MOVQ</code> inline assembly... but that's a crazy idea for another day)</p>



<a name="178198023"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178198023" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178198023">(Oct 15 2019 at 14:21)</a>:</h4>
<p>Given that this is a super edge case, I would personally be fine with a comment saying "this is UB, but it has low odds of happening, it is not known to have any observable consequence, and we don't have the right language tools for building the underlying synchronization protocol correctly and efficiently right now". But again, this comment is missing.</p>



<a name="178198879"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178198879" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178198879">(Oct 15 2019 at 14:31)</a>:</h4>
<p>Anyhow, overall, good job! I've tried to write a work-stealing scheduler myself in the past, and I'm well aware of how much painful it can get when things like blocking come into play. All I am saying is that perhaps you should document your achievement a little bit better so that future reviewers of the code get a more solid grasp of what's going on and why.</p>



<a name="178251967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178251967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> comex <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178251967">(Oct 16 2019 at 01:54)</a>:</h4>
<p>maybe not AtomicU8, but an AtomicU64 loop would be decently fast</p>



<a name="178251978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178251978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> comex <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178251978">(Oct 16 2019 at 01:54)</a>:</h4>
<p>I don't understand why atomic memcpy is needed here though</p>



<a name="178260198"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178260198" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178260198">(Oct 16 2019 at 05:23)</a>:</h4>
<p>Because ptr::read racing with ptr::write is generally not allowed, even if you discard the result after the fact. Whereas with a form of atomic memcpy the result is "well-defined": you get randomly torn garbage data.</p>



<a name="178260273"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178260273" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178260273">(Oct 16 2019 at 05:25)</a>:</h4>
<p>(IIUC, it's actually OK at the LLVM layer since they use a "data race returns undef" localized UB formalism rather than a messy C-like notion of global UB invalidating the whole program, so another way to handle this would be to integrate similar data race semantics to Rust... but I'm not sure if we are prepared to do that)</p>



<a name="178261623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178261623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178261623">(Oct 16 2019 at 06:03)</a>:</h4>
<p>In a way, this is somewhat related to my thread about padding bytes and memcpy: our current rules have a nasty tendency to turn some specific memory read and write operations into global program UB, and I'm not sure if this is actually fine.</p>



<a name="178261741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178261741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178261741">(Oct 16 2019 at 06:06)</a>:</h4>
<p>(in the padding bytes case, it's more egregious since making it UB to observe padding bytes makes it UB to move a Rust object in an efficient/obvious way... but I think this case is no less interesting)</p>



<a name="178262137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178262137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178262137">(Oct 16 2019 at 06:16)</a>:</h4>
<p>At the same time, it's definitely true that specific load/store operations are global program UB. Dereferencing a null pointer is, for example. So differencing between local and global UB would likely end up making the rules more complex ;)</p>



<a name="178311265"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178311265" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178311265">(Oct 16 2019 at 17:41)</a>:</h4>
<blockquote>
<p>Because ptr::read racing with ptr::write is generally not allowed, even if you discard the result after the fact. Whereas with a form of atomic memcpy the result is "well-defined": you get randomly torn garbage data.</p>
</blockquote>
<p>I dont think we have anything in the Rust semantics that gives you randomly turn garbage data. that would be <code>freeze</code> and we dont have it.</p>



<a name="178314465"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178314465" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178314465">(Oct 16 2019 at 18:12)</a>:</h4>
<p>Let me reformulate. It's not randomly torn. It's the perfectly reasonable result of a sequence of atomic reads targeting different memory locations, which happen tor return the values that were atomically written by different sequences of writes.</p>



<a name="178314508"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178314508" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178314508">(Oct 16 2019 at 18:13)</a>:</h4>
<p>And from a specification point of view, that's totally different.</p>



<a name="178314537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178314537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hadrien Grasland <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178314537">(Oct 16 2019 at 18:13)</a>:</h4>
<p>From a developer's point of view, however, it's randomly torn garbage data.</p>



<a name="178314661"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell%3CAtomicU32%3E/near/178314661" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/UnsafeCell.3CAtomicU32.3E.html#178314661">(Oct 16 2019 at 18:14)</a>:</h4>
<p>I see. fair :)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>